#pragma once

#include "stdafx.h"
#include "utf8.h"

NTSTATUS FbinstRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FbinstWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
BOOLEAN FbinstFastIoRead(__in struct _FILE_OBJECT *FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__out PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in struct _DEVICE_OBJECT *DeviceObject);
BOOLEAN FbinstFastIoWrite(__in struct _FILE_OBJECT *FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__in PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in struct _DEVICE_OBJECT *DeviceObject);
BOOLEAN FBFSFastQueryBasicInfo(__in struct _FILE_OBJECT *FileObject,__in BOOLEAN Wait,__out PFILE_BASIC_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in struct _DEVICE_OBJECT *DeviceObject);
NTSTATUS FBFSDirectoryControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSQueryFileInfo(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSSetFileInfo(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
BOOLEAN FBFSFastQueryStandardInfo(__in struct _FILE_OBJECT *FileObject,__in BOOLEAN Wait,__out PFILE_STANDARD_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in struct _DEVICE_OBJECT *DeviceObject);
BOOLEAN FBFSFastLock(
							__in struct _FILE_OBJECT *FileObject,
							__in PLARGE_INTEGER FileOffset,
							__in PLARGE_INTEGER Length,
							__in PEPROCESS ProcessId,
							__in ULONG Key,
							__in BOOLEAN FailImmediately,
							__in BOOLEAN ExclusiveLock,
							__out PIO_STATUS_BLOCK IoStatus,
							__in struct _DEVICE_OBJECT *DeviceObject
							);
NTSTATUS FBFSCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSCleanUp(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSFileSysControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
NTSTATUS FBFSLock(IN PDEVICE_OBJECT DeviceObject,IN PIRP IRPMess);

int EnmuDisk(OUT LIST_ENTRY* pDiskListHead);
int EnmuUD(IN LIST_ENTRY *pDiskListHead,OUT LIST_ENTRY *pUDListHead,IN PDRIVER_OBJECT DriverObject);
void GetUDFileLists(INOUT PLIST_ENTRY udDeviceList);
bool IfIsUD(wchar_t *DiskIDName);
void *memcat(void* Dst,const void* src,unsigned int offest,size_t srcLength);
void GetARecord(IN char *Original,OUT FileRecord *Record);
void GetUDFileLists(INOUT PLIST_ENTRY udDeviceList);
void EnmuFileList(INOUT DiskListEntry *Disk);
NTSTATUS FBFSPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRPMess);
char * GetCurrentProcessName(char * ProcessName);
void GetCurrentProcessName();

const UNICODE_STRING usDeviceName = RTL_CONSTANT_STRING(L"\\FileSystem\\FbinstFS");
const UNICODE_STRING usSymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\FbinstFS");

const int* except = NULL;

VOID KeSleep(LONG msec);

FBFS_DRIVER_EXT *pDriverExtension;

inline void EasyCompleteIRP(PIRP IRPMess,NTSTATUS status,ULONG_PTR Info);
NTSTATUS FBFSReadFile(FileRecord &FileHandle,void *buffer,size_t bufsize,size_t readsize,LARGE_INTEGER offest,IO_STATUS_BLOCK &IoStatus);
NTSTATUS Completion(PDEVICE_OBJECT DeviceObject,PIRP IRPMess,PVOID context);